/**
 * Copyright UOB Ltd. All rights reserved. (2011)
 *
 * This software is the confidential and proprietary information
 * of United Overseas Bank Ltd. ("Confidential Information"). 
 * You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the contract
 * agreement you entered into with UOB.
 * 
 * File Name  : SpringBeanFactory.java
 * Created By : Adelwin Handoyo
 * Created At : Apr 14, 2011 5:25:56 PM
 *
 * Change History
 * Author Name     Date        Details
 * =============== =========== =================================
 * Adelwin Handoyo Apr 14, 2011 Initial Draft
 */
package com.uobgroup.cmt.base.factory;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.uobgroup.cmt.base.config.ConfigurationUtil;
import com.uobgroup.cmt.base.exception.BaseException;
import com.uobgroup.cmt.base.exception.BaseRuntimeException;

public class SpringBeanFactory extends BeanFactory {
	protected Logger logger = Logger.getLogger(SpringBeanFactory.class);
	protected ApplicationContext springApplicationContext;
	
	private SpringBeanFactory() {
		String springConfigFileNames = ConfigurationUtil.getInstance().getConfigurationValue(ConfigurationUtil.KEY_SPRING_CONFIGFILELOCATION);
		this.init(springConfigFileNames);
	}
	
	private static class SingletonHolder {
		public static final SpringBeanFactory INSTANCE = new SpringBeanFactory();
	}
	
	public static SpringBeanFactory getInstance() {
		return SingletonHolder.INSTANCE;
	}
	
	public void init(String springConfigFileNames) throws BaseRuntimeException {
		try {
			logger.info("Initializing local spring bean factory");
			logger.info("spring config file names : " + springConfigFileNames);
			String[] configFileNames = springConfigFileNames.split(",");
			springApplicationContext = new ClassPathXmlApplicationContext(configFileNames);
			logger.info("local spring bean factory initialized");
		} catch (Exception e) {
			logger.error("failed initializing local spring bean factory", e);
			e.printStackTrace();
			throw new BaseRuntimeException(e.getMessage(), e);
		}
	}
	
	/**
	 * Minimum implementation,
	 * initially provided to delay spring context instantiation as late as possible.
	 * provided to create an abstract layer of bean instantiation on later stage.
	 * @param className
	 * @return
	 * @throws BaseException
	 */
	public Object getBean(String className) throws BaseException {
		try {
			Object retVal = this.springApplicationContext.getBean(className);
			logger.debug("returning an instance of " + className);
			return retVal;
		} catch (Exception e) {
			logger.error("failed retrieving bean from local factory", e);
			e.printStackTrace();
			throw new BaseException(e.getMessage(), e);
		}
	}
	
	public Object getBean(Class<?> clazz) throws BaseException {
		return this.getBean(clazz.getName());
	}
}
